﻿using CommandLib;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using WebSocketSharp;

namespace BibilToMp4
{
    public class M4SToVico
    {
        private string _scouce;
        private string _tagfile;

        private List<Vmodel> vmodels;
        public M4SToVico(string scourc, string tagfile)
        {
            _scouce = scourc;
            _tagfile = tagfile;
            if (!string.IsNullOrWhiteSpace(_tagfile))
            {

                if (!Directory.Exists(_tagfile))
                {
                    Directory.CreateDirectory(_tagfile);
                }
            }
            if (Directory.Exists(_scouce))
            {

                vmodels = new List<Vmodel>();
                var dirs = Directory.GetDirectories(_scouce);
                foreach (var dir in dirs)
                {

                    var fs = Directory.GetFiles(dir, "*.m4s");
                    var path = $@"{dir}\.videoInfo";
                    if (File.Exists(path))
                    {
                        var json = FileHelper.ReadFile(path, Encoding.UTF8);
                        if (!string.IsNullOrEmpty(json))
                        {
                            var models = json.JsonToObject<Vmodel>();
                            models.files = fs;
                            vmodels.Add(models);
                        }
                    }

                }

            }


        }

        public void Run()
        {

            if (vmodels != null)
            {
                vmodels.ForEach(f =>
                {
                    if (f.files != null && f.files.Length > 1)
                    {
                        Console.WriteLine($"m4s文件解密!");
                        cutHead9(f.files);
                        try
                        {
                            Console.WriteLine("文件合并为MP4!");
                            var path = $@"{_tagfile}\{f.title.Replace(" ","_")}.mp4";
                            if (File.Exists(path))
                            {
                                Console.WriteLine($"{path}已存在！");
                            }
                            else {                                        

                                var cmd1 = $" -i {f.files[0]} -i {f.files[1]} -c:v copy -c:a aac -strict experimental {path} ";
                                CommandManager(cmd1);
                                Console.WriteLine($"{DateTime.Now}转换地址：{path}");
                            }                         

                          
                        }
                        catch (Exception ex)
                        {
                            Console.WriteLine(ex.ToString());

                        }

                    }

                });
            }


        }

        /// <summary>
        /// 去掉文件头9个字节
        /// </summary>
        /// <param name="files"></param>

        public void cutHead9(string[] files)
        {
            if (files != null && files.Length > 0)
            {
                for (int i = 0; i < files.Length; i++)
                {
                    var bt = FileContent(files[i]);
                    if (bt != null && bt.Length > 9)
                    {
                        if (checkHead(bt))
                        {
                            bt = bt.SubArray(9, bt.Length - 9);
                            byteArraySave(bt, files[i]);
                        }
                      
                    }
                }

            }

        }

        /// <summary>
        /// 校验文件头是否被转换过 true 表示可转换，false 不能转换
        /// </summary>
        /// <param name="bytesHead"></param>
        /// <returns></returns>
        private bool checkHead(byte[] bytesHead)
        {
            var result = true;
            if (bytesHead != null)
            {
                for (int i = 0; i < 9; i++)
                {
                    if (bytesHead[i] == 48)
                    {
                        result = true;
                    }
                    else
                    {
                        return false;
                    }
                }
            }
            else
            {
                return false;
            }

            return result;

        }


        /// <summary>
        /// 文件转流
        /// </summary>
        /// <param name="fileName"></param>
        /// <returns></returns>

        private byte[] FileContent(string fileName)
        {
            using (FileStream fs = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
            {
                try
                {
                    byte[] buffur = new byte[fs.Length];
                    fs.Read(buffur, 0, (int)fs.Length);
                    return buffur;
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
        /// <summary>
        /// 流转文件
        /// </summary>
        /// <param name="byteArray"></param>
        /// <param name="filePath"></param>

        private void byteArraySave(byte[] byteArray, string filePath)
        {


            using (FileStream fs = new FileStream(filePath, FileMode.Create, FileAccess.Write))
            {
                fs.Write(byteArray, 0, byteArray.Length);
            }
        }


        public  void CommandManager(string commandStr)
        {
            try
            {
                using (Process process = new Process())
                {
                    ////要执行的程序名称(属性，获取或设置要启动的应用程序或文档。FileName 属性不需要表示可执行文件。 它可以是其扩展名已经与系统上安装的应用程序关联的任何文件类型。)
                    process.StartInfo.FileName = @$"{AppDomain.CurrentDomain.BaseDirectory}ffmpeg.exe";
                    //启动该进程时传递的命令行参数
                    process.StartInfo.Arguments = " " + commandStr;
                    process.StartInfo.UseShellExecute = false;
                    //可能接受来自调用程序的输入信息  
                    process.StartInfo.RedirectStandardInput = false;
                    //由调用程序获取输出信息   
                    process.StartInfo.RedirectStandardOutput = false;
                    //重定向标准错误输出
                    process.StartInfo.RedirectStandardError = false;
                    //不显示程序窗口
                    process.StartInfo.CreateNoWindow = false;
                    //启动程序
                    process.Start();
                    //等待程序执行完退出进程(避免进程占用文件或者是合成文件还未生成)*
                    process.WaitForExit();
                }
            }
            catch (Exception e)
            {
                Console.WriteLine(e.Message);
            }
        }
    }
    



    public class Vmodel
    {

        /// <summary>
        /// 集数
        /// </summary>
        public string p { get; set; }
        /// <summary>
        /// 标题
        /// </summary>
        public string title { get; set; }
        /// <summary>
        /// 文件夹组
        /// </summary>

        public long itemId { get; set; }
        /// <summary>
        /// 文件路径
        /// </summary>

        public string[] files { get; set; }

    }

}
